package com.example.gfile.random;

import com.example.gfile.entity.Filed;
import com.example.gfile.entity.ChainFiled;
import com.example.gfile.util.UniCodeSeparatorUtil;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class ChainRandomData implements IRandomData {

    private static final Map<String, IRandomData> serviceMap = new HashMap<>();

    public ChainRandomData(List<IRandomData> dataList) {
        dataList.forEach(service -> serviceMap.put(service.type(), service));
    }

    @Override
    public String type() {
        return LIST_TYPE;
    }

    @Override
    public Function<Filed, String> data() {
        return filed -> {
            ChainFiled chainFiled = filed.getChainFiled();

            String collPrefix = chainFiled.getCollPrefix();
            String collSuffix = chainFiled.getCollSuffix();
            int elementCount = chainFiled.getCollElementCount();
            String elementSeparator = UniCodeSeparatorUtil.convert(chainFiled.getCollElementSeparator());
            String chainPrefix = chainFiled.getChainPrefix();
            String chainSuffix = chainFiled.getChainSuffix();
            String separator = UniCodeSeparatorUtil.convert(chainFiled.getSeparator());
            List<Filed> chainFiledList = chainFiled.getChainFiledList();
            StringBuilder builder = new StringBuilder(1000);
            builder.append(collPrefix);
            List<String> filedListStr = new ArrayList<>();
            for (int i = 0; i < elementCount; i++) {
                StringBuilder filedStr = new StringBuilder();
                filedStr.append(chainPrefix);

                List<String> filedList = chainFiledList.stream().map(filed1 -> {
                    IRandomData iRandomDataImpl = serviceMap.get(filed1.getType());
                    Function<Filed, String> function = iRandomDataImpl.data();
                    return function.apply(filed1);
                }).collect(Collectors.toList());
                filedStr.append(String.join(separator, filedList));

                filedStr.append(chainSuffix);
                filedListStr.add(filedStr.toString());
            }
            builder.append(String.join(elementSeparator, filedListStr));

            builder.append(collSuffix);
            return builder.toString();
        };
    }
}
